package com.necer.painter;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;

import androidx.core.content.ContextCompat;

import com.necer.calendar.ICalendar;
import com.necer.entity.CalendarDate;
import com.necer.utils.Attrs;
import com.necer.utils.CalendarUtil;
import com.necer.utils.DrawableUtil;

import org.joda.time.LocalDate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CustomInfoPainter implements CalendarPainter {

    private Attrs mAttrs;
    private Paint mTextPaint;

    private int noAlphaColor = 255;
    private int mBackgroundWidth;

    private Map<LocalDate, String> mInfoMap;

    private ICalendar mCalendar;

    private Drawable mDefaultCheckedBackground;
    private Drawable mDefaultUnCheckedBackground;
    private Drawable mTodayCheckedBackground;
    private Drawable mTodayUnCheckedBackground;

    public CustomInfoPainter(Context context, ICalendar calendar) {
        this.mAttrs = calendar.getAttrs();
        this.mCalendar = calendar;

        mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextAlign(Paint.Align.CENTER);

        mInfoMap = new HashMap<>();

        mDefaultCheckedBackground = ContextCompat.getDrawable(context, mAttrs.defaultCheckedBackground);
        mDefaultUnCheckedBackground = ContextCompat.getDrawable(context, mAttrs.defaultUnCheckedBackground);
        mTodayCheckedBackground = ContextCompat.getDrawable(context, mAttrs.todayCheckedBackground);
        mTodayUnCheckedBackground = ContextCompat.getDrawable(context, mAttrs.todayUnCheckedBackground);
    }

    public void setDefaultCheckedBackground(Drawable defaultCheckedBackground) {
        mDefaultCheckedBackground = defaultCheckedBackground;
    }

    public void setDefaultUnCheckedBackground(Drawable defaultUnCheckedBackground) {
        mDefaultUnCheckedBackground = defaultUnCheckedBackground;
    }

    public void setTodayCheckedBackground(Drawable todayCheckedBackground) {
        mTodayCheckedBackground = todayCheckedBackground;
    }

    public void setTodayUnCheckedBackground(Drawable todayUnCheckedBackground) {
        mTodayUnCheckedBackground = todayUnCheckedBackground;
    }

    public Attrs getAttrs() {
        return mAttrs;
    }

    @Override
    public void onDrawToday(Canvas canvas, RectF rectF, LocalDate localDate, List<LocalDate> checkedDateList, int lineNum) {
        if (checkedDateList.contains(localDate)) {
            drawCheckedBackground(canvas, mTodayCheckedBackground, rectF, noAlphaColor);
            drawSolar(canvas, rectF, localDate, mAttrs.todayCheckedSolarTextColor, noAlphaColor);
            drawInfo(canvas, rectF, localDate, mAttrs.todayCheckedLunarTextColor, noAlphaColor);
        } else {
            drawCheckedBackground(canvas, mTodayUnCheckedBackground, rectF, noAlphaColor);
            drawSolar(canvas, rectF, localDate, mAttrs.todayUnCheckedSolarTextColor, noAlphaColor);
            drawInfo(canvas, rectF, localDate, mAttrs.todayUnCheckedLunarTextColor, noAlphaColor);
        }
    }

    @Override
    public void onDrawCurrentMonthOrWeek(Canvas canvas, RectF rectF, LocalDate localDate, List<LocalDate> checkedDateList, int lineNum) {
        if (checkedDateList.contains(localDate)) {
            drawCheckedBackground(canvas, mDefaultCheckedBackground, rectF, noAlphaColor);
            drawSolar(canvas, rectF, localDate, mAttrs.defaultCheckedSolarTextColor, noAlphaColor);
            drawInfo(canvas, rectF, localDate, mAttrs.defaultCheckedLunarTextColor, noAlphaColor);
        } else {
            drawCheckedBackground(canvas, mDefaultUnCheckedBackground, rectF, noAlphaColor);
            drawSolar(canvas, rectF, localDate, mAttrs.defaultUnCheckedSolarTextColor, noAlphaColor);
            drawInfo(canvas, rectF, localDate, mAttrs.defaultUnCheckedLunarTextColor, noAlphaColor);
        }
    }

    @Override
    public void onDrawLastOrNextMonth(Canvas canvas, RectF rectF, LocalDate localDate, List<LocalDate> checkedDateList, int lineNum) {
        if (checkedDateList.contains(localDate)) {
            drawCheckedBackground(canvas, mDefaultCheckedBackground, rectF, mAttrs.lastNextMothAlphaColor);
            drawSolar(canvas, rectF, localDate, mAttrs.defaultCheckedSolarTextColor, mAttrs.lastNextMothAlphaColor);
            drawInfo(canvas, rectF, localDate, mAttrs.defaultCheckedLunarTextColor, mAttrs.lastNextMothAlphaColor);
        } else {
            drawCheckedBackground(canvas, mDefaultUnCheckedBackground, rectF, mAttrs.lastNextMothAlphaColor);
            drawSolar(canvas, rectF, localDate, mAttrs.defaultUnCheckedSolarTextColor, mAttrs.lastNextMothAlphaColor);
            drawInfo(canvas, rectF, localDate, mAttrs.defaultUnCheckedLunarTextColor, mAttrs.lastNextMothAlphaColor);
        }
    }

    @Override
    public void onDrawDisableDate(Canvas canvas, RectF rectF, LocalDate localDate, List<LocalDate> checkedDateList, int lineNum) {
        drawCheckedBackground(canvas, mDefaultUnCheckedBackground, rectF, mAttrs.lastNextMothAlphaColor);
        drawSolar(canvas, rectF, localDate, mAttrs.defaultUnCheckedSolarTextColor, mAttrs.disabledAlphaColor);
        drawInfo(canvas, rectF, localDate, mAttrs.defaultUnCheckedLunarTextColor, mAttrs.disabledAlphaColor);
    }

    //选中背景
    private void drawCheckedBackground(Canvas canvas, Drawable drawable, RectF rectF, int alphaColor) {
        Rect drawableBounds = DrawableUtil.getDrawableBounds((int) rectF.centerX(), (int) rectF.centerY(), drawable);
        drawable.setBounds(drawableBounds);
        drawable.setAlpha(alphaColor);
        drawable.draw(canvas);
        mBackgroundWidth = drawableBounds.right - drawableBounds.left;
    }

    //绘制公历
    private void drawSolar(Canvas canvas, RectF rectF, LocalDate date, int color, int alphaColor) {
        mTextPaint.setColor(color);
        mTextPaint.setAlpha(alphaColor);
        mTextPaint.setTextSize(mAttrs.solarTextSize);
        mTextPaint.setFakeBoldText(mAttrs.solarTextBold);
        canvas.drawText(date.getDayOfMonth() + "", rectF.centerX(),
                mAttrs.showLunar ? rectF.centerY() - 4 : getTextBaseLineY(rectF.centerY()), mTextPaint);
    }

    //绘制信息栏
    private void drawInfo(Canvas canvas, RectF rectF, LocalDate localDate, int color, int alphaColor) {
        CalendarDate calendarDate = CalendarUtil.getCalendarDate(localDate);
        //农历部分文字展示优先顺序 替换的文字、农历节日、节气、公历节日、正常农历日期
        String infoStr = mInfoMap.get(localDate);
        if (!TextUtils.isEmpty(infoStr)) {
            mTextPaint.setColor(color);
            mTextPaint.setTextSize(mAttrs.lunarTextSize);
            mTextPaint.setAlpha(alphaColor);
            mTextPaint.setFakeBoldText(mAttrs.lunarTextBold);

            String checkStr = infoStr;
            float textWidth = mTextPaint.measureText(checkStr);
            int cutCount = 2;
            while (textWidth > mBackgroundWidth) {
                checkStr = infoStr.substring(0, infoStr.length() - cutCount) + "...";
                textWidth = mTextPaint.measureText(checkStr);
                cutCount++;
            }
            canvas.drawText(checkStr, rectF.centerX(), rectF.centerY() + mAttrs.lunarDistance - 14, mTextPaint);
        }
    }

    //canvas.drawText的基准线
    private float getTextBaseLineY(float centerY) {
        Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
        return centerY - (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.top;
    }

    //设置info
    public void setInfoMap(Map<String, String> infoMap) {
        mInfoMap.clear();
        for (String key : infoMap.keySet()) {
            LocalDate localDate;
            try {
                localDate = new LocalDate(key);
            } catch (Exception e) {
                throw new RuntimeException("setInfoMap的参数需要 yyyy-MM-dd 格式的日期");
            }
            mInfoMap.put(localDate, infoMap.get(key));
        }
        mCalendar.notifyCalendar();
    }
}
